package com.myzl.quartz.task;

import com.myzl.coal.domain.Device;
import com.myzl.coal.mapper.DeviceMapper;
import com.myzl.coal.service.IDeviceService;
import com.myzl.coal.service.ILEDScreenService;
import com.myzl.coal.utils.HexUtil;
import com.myzl.common.constant.LedCacheKeyConstants;
import com.myzl.common.core.redis.RedisCache;
import com.myzl.common.enums.DeviceTypeEnum;
import com.myzl.common.enums.LedScreenContent;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author Administrator
 * @date 2022年10月25日14:45:52
 */
@Component("ledTask")
@Slf4j
@Data
public class LedTask {
    private final RedisCache redisCache;
    private final DeviceMapper deviceMapper;
    private final IDeviceService deviceService;
    private final ILEDScreenService ledScreenService;
    Map<Integer,Integer> contentIndexMap=new ConcurrentHashMap<>();

    public void sendData() {
        List<Device> deviceByDeviceTypeList = deviceService.getDeviceByDeviceTypeList(DeviceTypeEnum.LED_SCREEN.getCode());
        deviceByDeviceTypeList.forEach(led -> {
            Integer contentIndex_pre = contentIndexMap.getOrDefault(led.getId(), -1);
            List<Integer> contentList = redisCache.getCacheList(redisCache.getLedCacheKey(LedCacheKeyConstants.LED_CONTENT));
            Integer contentIndex = contentList.stream().sorted(Integer::compareTo).filter((f)->f>contentIndex_pre).limit(1)
                    .collect(Collectors.reducing(contentList.get(0), Integer::max));
            LedScreenContent ledScreenContent = LedScreenContent.toType(contentIndex);

            List<Device> doubleOrder = deviceService.getDeviceByGroupId(led.getDeviceGroup(), DeviceTypeEnum.DOUBLE_ORDER.getCode());
            if (CollectionUtils.isEmpty(doubleOrder)){
                log.info("没有对应双目设备");
                return;
            }
            String content = ledScreenService.getDisPlayData(doubleOrder.get(0).getId(),ledScreenContent);

            Integer screenColor = Integer.parseInt(redisCache.getCacheObject(redisCache.getLedCacheKey(LedCacheKeyConstants.LED_COLOR)));
            String szCardIP = led.getIp();

            log.info("deviceId {},led send data:{}",led.getId(), content);
            ledSend(content, screenColor, szCardIP);
            contentIndexMap.put(led.getId(),contentIndex);
        });

    }

    private void ledSend(String content, Integer screenColor, String szCardIP) {
        try {
            int fontSize = 1; //0:12*12  1:16*16  2:24*24 3:32*32
            int singleSize;
            if (fontSize == 0) {
                singleSize = 12;
            } else if (fontSize == 1) {
                singleSize = 16;
            } else if (fontSize == 2) {
                singleSize = 24;
            } else {
                singleSize = 32;
            }

            int dataLen = content.getBytes("GB2312").length;
            int totalLen = 192 / singleSize * 2;
            int diffLen = (totalLen - dataLen) / 2;
            if (diffLen > 0) {
                int realDataLen = content.length() + diffLen;
                content = String.format("%" + realDataLen + "s", content);
            }

            byte[] bytes = SendInternalText_Net_test(content, szCardIP, 1, 192, 16, 1, screenColor,
                    1, 5, 3, screenColor, 1, fontSize,
                    2, false, 0);
            log.info("led send data:{}", HexUtil.bytesToHexString(bytes));
            // 创建发送方 DatagramSocket 对象
            DatagramSocket socket = new DatagramSocket();
            DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getByName(szCardIP), 8800);
            socket.send(packet);
            socket.close();

        } catch (UnsupportedEncodingException unsupportedEncodingException) {
            log.error("led发送失败：", unsupportedEncodingException);
        } catch (Exception exception) {
            log.error("led发送失败：", exception);
            exception.printStackTrace();
        } finally {
        }
    }


    public static byte[] InternalTextBuffer(String szShowContent, int nAreaWidth, int nAreaHigth, int nUID, int nScreenColor, int nShowStyle, int nShowSpeed, int nStopTime, int nFontColor, int nFontBody, int nFontSize, int nUpdateStyle, boolean bPowerOffSave, int nRotateMode, boolean bEnd) {
        byte[] byPacketBuffer = new byte[0];

        try {
            if (nUpdateStyle == 3) {
                bEnd = false;
            }

            byte[] byContent = szShowContent.getBytes("GB2312");
            int nContentLen = byContent.length;
            int nPackLen = nContentLen + 62;
            if (bEnd) {
                nPackLen += 3;
            }

            byPacketBuffer = new byte[nPackLen];
            int nArrIndex = 0;
            String szUID = String.format("%09d", nUID);

            int nWidth;
            for (nWidth = 0; nWidth < 9; ++nWidth) {
                byPacketBuffer[nArrIndex++] = (byte) szUID.charAt(nWidth);
            }

            byPacketBuffer[nArrIndex++] = 44;
            byPacketBuffer[nArrIndex++] = (byte) nShowStyle;
            byPacketBuffer[nArrIndex++] = (byte) nShowSpeed;
            byPacketBuffer[nArrIndex++] = (byte) nStopTime;
            byPacketBuffer[nArrIndex++] = 48;
            byPacketBuffer[nArrIndex++] = 49;
            byPacketBuffer[nArrIndex++] = 48;
            byPacketBuffer[nArrIndex++] = 49;
            byPacketBuffer[nArrIndex++] = 48;
            byPacketBuffer[nArrIndex++] = 49;
            byPacketBuffer[nArrIndex++] = 57;
            byPacketBuffer[nArrIndex++] = 57;
            byPacketBuffer[nArrIndex++] = 49;
            byPacketBuffer[nArrIndex++] = 50;
            byPacketBuffer[nArrIndex++] = 51;
            byPacketBuffer[nArrIndex++] = 49;
            byPacketBuffer[nArrIndex++] = 19;
            byPacketBuffer[nArrIndex++] = 0;
            byPacketBuffer[nArrIndex++] = 0;
            byPacketBuffer[nArrIndex++] = 0;
            byPacketBuffer[nArrIndex++] = 85;
            byPacketBuffer[nArrIndex++] = -86;
            byPacketBuffer[nArrIndex++] = 0;
            byPacketBuffer[nArrIndex++] = (byte) nRotateMode;
            byPacketBuffer[nArrIndex++] = 55;
            byPacketBuffer[nArrIndex] = 50;
            if (bPowerOffSave) {
                byPacketBuffer[nArrIndex] = 49;
            }

            ++nArrIndex;
            byPacketBuffer[nArrIndex] = 49;
            if (nUpdateStyle == 2) {
                byPacketBuffer[nArrIndex] = 50;
            } else if (nUpdateStyle == 3) {
                byPacketBuffer[nArrIndex] = 51;
            }

            ++nArrIndex;
            byPacketBuffer[nArrIndex++] = 49;
            byPacketBuffer[nArrIndex] = 49;
            if (nScreenColor == 1) {
                byPacketBuffer[nArrIndex] = 50;
            } else if (nScreenColor == 2) {
                byPacketBuffer[nArrIndex] = 51;
            }

            ++nArrIndex;
            byPacketBuffer[nArrIndex++] = 49;
            byPacketBuffer[nArrIndex++] = 0;
            byPacketBuffer[nArrIndex++] = 0;
            nWidth = nAreaWidth / 8;
            byPacketBuffer[nArrIndex++] = (byte) nWidth;
            byPacketBuffer[nArrIndex++] = (byte) (nWidth >> 8);
            byPacketBuffer[nArrIndex++] = (byte) nAreaHigth;
            byPacketBuffer[nArrIndex++] = (byte) (nAreaHigth >> 8);
            byPacketBuffer[nArrIndex++] = (byte) nFontColor;
            byPacketBuffer[nArrIndex++] = (byte) (nFontBody << 4 | nFontSize);
            byPacketBuffer[nArrIndex++] = 0;
            int nLen = nContentLen + 10;
            byPacketBuffer[nArrIndex++] = (byte) nLen;
            byPacketBuffer[nArrIndex++] = (byte) (nLen >> 8);
            byPacketBuffer[nArrIndex++] = (byte) (nLen >> 16);
            byPacketBuffer[nArrIndex++] = (byte) (nLen >> 24);

            for (int i = 0; i < nContentLen; ++i) {
                byPacketBuffer[nArrIndex++] = byContent[i];
            }

            byPacketBuffer[nArrIndex++] = -1;
            byPacketBuffer[nArrIndex++] = 0;
            byPacketBuffer[nArrIndex++] = 1;
            byPacketBuffer[nArrIndex++] = 0;
            byPacketBuffer[nArrIndex++] = 1;
            byPacketBuffer[nArrIndex++] = 0;
            byPacketBuffer[nArrIndex++] = 1;
            byPacketBuffer[nArrIndex++] = 0;
            byPacketBuffer[nArrIndex++] = 0;
            byPacketBuffer[nArrIndex++] = 0;
            if (bEnd) {
                byPacketBuffer[nArrIndex++] = 45;
                byPacketBuffer[nArrIndex++] = 49;
                byPacketBuffer[nArrIndex++] = 44;
            }
        } catch (Exception var24) {
        }

        return byPacketBuffer;
    }

    public static byte[] CompletePacketBuffer(byte[] byContent, short nMsgType, int nForwordPort) {
        int nContentLen = byContent.length;
        int nPackLen = nContentLen + 19;
        byte[] byPacketBuffer = new byte[nPackLen];
        int nArrIndex = 0;
        int var8 = nArrIndex + 1;
        byPacketBuffer[nArrIndex] = -2;
        byPacketBuffer[var8++] = 92;
        byPacketBuffer[var8++] = 75;
        byPacketBuffer[var8++] = -119;
        byPacketBuffer[var8++] = (byte) nPackLen;
        byPacketBuffer[var8++] = (byte) (nPackLen >> 8);
        byPacketBuffer[var8++] = (byte) (nPackLen >> 16);
        byPacketBuffer[var8++] = (byte) (nPackLen >> 24);
        byPacketBuffer[var8++] = (byte) nMsgType;
        byPacketBuffer[var8++] = (byte) nForwordPort;
        byPacketBuffer[var8++] = 0;
        byPacketBuffer[var8++] = 0;
        byPacketBuffer[var8++] = 0;
        byPacketBuffer[var8++] = (byte) nContentLen;
        byPacketBuffer[var8++] = (byte) (nContentLen >> 8);
        byPacketBuffer[var8++] = (byte) (nContentLen >> 16);
        byPacketBuffer[var8++] = (byte) (nContentLen >> 24);

        for (int i = 0; i < nContentLen; ++i) {
            byPacketBuffer[var8++] = byContent[i];
        }

        byPacketBuffer[var8++] = -1;
        byPacketBuffer[var8++] = -1;
        return byPacketBuffer;
    }

    public static byte[] SendInternalText_Net_test(String szShowContent, String szCardIP, int nNetProtocol, int nAreaWidth, int nAreaHeight, int nUID, int nScreenColor, int nShowStyle, int nShowSpeed, int nStopTime, int nFontColor, int nFontBody, int nFontSize, int nUpdateStyle, boolean bPowerOffSave, int nRotateMode) throws IOException {
        byte[] byContent = InternalTextBuffer(szShowContent, nAreaWidth, nAreaHeight, nUID, nScreenColor, nShowStyle, nShowSpeed, nStopTime, nFontColor, nFontBody, nFontSize, nUpdateStyle, bPowerOffSave, nRotateMode, true);
        byte[] byPacketBuffer = CompletePacketBuffer(byContent, (short) 49, 0);

        return byPacketBuffer;
    }

}
